// EvaluatingPanesMap.h : interface of the CEvaluatingPanesMap class

// Deklaracia mapy ohodnocovacich policok realizovanej ako dynamicke pole ohodnocovacich policok 

#ifndef EVALUATING_PANES_MAP_H
#define EVALUATING_PANES_MAP_H

#include "Dynamic2dArray.h"
#include "EvaluatingPane.h"
#include "EvaluatingPlayer.h" 

#include <time.h>

// FIXNE PARAMETRE PROTOTYPU

	// Originalna sirka ihriska z RC (RoboCup)
	const int nOriginalPlaygroundWidth = 105;

	// Originalna vyska ihriska z RC
	const int nOriginalPlaygroundHeight = 68;

	// Default ohodnotenie policok prveho stlpca + prirastok pre kazdy dalsi (smerom k superovej brane)
	const double lfDefaultEvValue = 22.0; const double lfDefaultEvStep = 1.5; // (povodne 20.0 a 5.0)

	// Bonusove ohodnotenie policok v istom polomere od superovej branky, ktore sa z jej vzdialenostou znizuje.
	// Nasledujuca hodnota predstavuje maximalny bonus, ktory moze policko dosiahnut
	const int lfMaxOffenseBonus = 22;

	// Bonusove ohodnotenie policok v istom polomere od nasej branky, ktore sa z jej vzdialenostou zvysuje.
	// Nasledujuca hodnota predstavuje maximalny bonus, ktory moze policko dosiahnut
	const int lfMaxDefenseBonus = -22;

	// Sila vplyvu daneho hraca na policko, na ktorom posobi
	const int nInfluencePower = 25; // (povodne 15)

	// Maximalna vzdialenost posobenia vplyvu daneho hraca v [metroch]
	const int nInfluenceSize = 10; // (povodne 10)   velkosPolicka * zelanyPolomer

	// Vyhadzovat informacie starsie ako nMaxAgeInformation
	const int nMaxAgeInformation = 6;

	// Maximalny sum vizualnej informacie. Pouziva si pri odstranovani duplicitnych informacii o hracoch.
	const double lfMaxVisualInfoNoise = 2.5;

	// Minimalna vzdialenost medzi dvoma hracmi pre nahravanie
	const double lfMinPassDistance = 3.0;

	// Maximalna vzdialenost medzi dvoma hracmi, ktora ma este zmysel pre nahravanie
	const double lfMaxPassDistance = 30.0;

	// Minimalny polomer oblasti, v ktorej hrac moze ocakavat prihravku
	const double lfMinPassAreaRadius = 2.0;

	// Maximalny polomer oblasti, v ktorej hrac moze ocakavat prihravku
	const double lfMaxPassAreaRadius = 9.0;

	// Definovanie ludolfovho cisla
	const double pi = 3.1415926535;

class CEvaluatingPanesMap
{
	// Dynamicke pole pointrov na ohodnocovacie policka
	CDynamic2dArray<CEvaluatingPane*> ePanes;

	// Velkost policka (zadavany ako vstupny parameter pre mapu)
	const double lfPaneSize;

	// Pocet policok v smere osi X (pre dynamicke pole)
	int nPanesXCount;
	// Pocet policok v smere osi Y (pre dynamicke pole)
	int nPanesYCount;


public:

	// Konstruktor
	CEvaluatingPanesMap(double PaneSize) : lfPaneSize(PaneSize)
	{			
		nPanesXCount = 0; nPanesYCount = 0;

		//inicializuje sa generator nahodnych cisiel (a vyuzije sa pri vybere jedneho z viacerych policok)  
		srand((unsigned)time(NULL));
	}
	
	// Destruktor
	~CEvaluatingPanesMap();
	
	// OSTATNE METODY

	// Vypocita najvhodnejsi bod pre driblovanie z hladiska ohodnotenych policok
	bool CalculateOptimalDribblePoint(double& lfDribblePosX, double& lfDribblePosY, double lfRadius);
	
	// Vypocita najvhodnejsie miesto na brankovej ciare, kam by mal hrac vystrelit
	void CalculateOptimalShootPoint(double& lfShootPosX, double& lfShootPosY, double lfHalfGoalSize);

	// Vypocita X-ovy rozmer pre dynamicke pole (pocet policok)
	int CalculatePanesXCount()
	{
		nPanesXCount =  CalculatePanesAxisCount(nOriginalPlaygroundHeight);
		return nPanesXCount;
	}

	// Vypocita Y-ovy rozmer pre dynamicke pole (pocet policok)
	int CalculatePanesYCount()
	{
		nPanesYCount = CalculatePanesAxisCount(nOriginalPlaygroundWidth);
		return nPanesYCount;
	}

	// Vypocita pocet policok v X-ovej (Vyska ako vstupny parameter) alebo Y-ovej osi (Sirka ako vstupny parameter)
	int CalculatePanesAxisCount(int nOriginalPlaygroundSize);

	// Vypocita vzdialenost policka od pozicie hraca
	double CalculatePaneDistanceFromPlayer(double lfPanePosX, double lfPanePosY, double lfPlayerPosX, double lfPlayerPosY);

	// Vypocita ohodnotenie priamky,ktora predstavuje diskretizovanu drahu nahravky. Priamka je samplovana
	// z bodu 1 do bodu 2 s istym krokom.
	double CalculateSamplingPassLineEvaluation(double lfPoint1X, double lfPoint1Y, double lfPoint2X, double lfPoint2Y, double lfStep);

	// Pociatocne ohodnotenie policok 
	void DefaultEvaluating(double lfDefaultValue, double lfDefaultStep);
	
	// Vytvori policka a napli ich suradnicami
	void FillPanesCoordinates();

	// Vygeneruje nahodny index z intervalu <0, nMaxIndex>
	int GenerateRandomIndex(int nMaxIndex);

	// Vrati velkost policka (pouziva sa pre stvorcove policko)
	double GetPaneSize()
	{
		return lfPaneSize;
	}

	// Vrati X-ovy rozmer dynamickeho pola
	int GetPanesXCount()
	{
		return nPanesXCount;
	}
	
	// Vrati Y-ovy rozmer dynamickeho pola
	int GetPanesYCount()
	{
		return nPanesYCount;
	}
	
	// Vrati policko na suradniciach [X,Y]
	CEvaluatingPane* GetXYPane(int nXIndex, int nYIndex)
	{
		return ePanes[nXIndex][nYIndex];
	}

	// Funkcia sa stara o predpripravne kroky ako napr. vytvorenie dynamickeho pola spravnych rozmerov, atd.
	void InitEvaluatingPanesMap(bool bLeft);

	// Zisti, ci bod lezi v obdlznikovej oblasti (aj na hranach)
	bool IsInRectArea(double lfPointX, double lfPointY, double lfLeft, double lfTop, double lfRight, double lfBottom);
	
	// Je policko pod vplyvom hraca?
	bool IsPaneUnderPlayerInfluence(CEvaluatingPlayer* pEvPlayer, CEvaluatingPane* ePane, int nRadius, int nXPos, int nYPos);

	// Nachadza sa bod v trojuholniku?
	bool IsPointInTriangle(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3);
	
	// Neprechadza index hranice ihriska (horizonalne/vertikalne)?
	bool IsValidIndex(int nPos, bool nHorizonal);

	// Namapuje suradnice bodu do XY pozicie, ak je bod priesecnikom 2 alebo 4 obdlznikov, tak vyberie jeden nahodne
	bool MapCoordinatesIntoPositions(double lfPointX, double lfPointY, int& nPositionX, int& nPositionY);

	// Vypocita nove suradnice bodu otoceneho o isty uhol okolo stredoveho bodu
	void RotatePoint(double lfPointCenterX, double lfPointCenterY, double& lfPoint1X, double& lfPoint1Y, double lfRadUhol);

	// Transformuje vplyv hraca do mapy ohodnocovacich policok
	void TransformPlayerInfluenceIntoEvaluatingPanesMap(CEvaluatingPlayer* pEvPlayer);
	int TransformPlayerInfluenceIntoEvaluatingPanesMapAux(CEvaluatingPlayer* pEvPlayer, int nXPos, int nYPos, int nRadius);
		
};


#endif // EVALUATING_PANES_MAP_H
